<template>
  <PageWrapper v-loading="loadingRef" content-full-height fixed-height content-class="flex">
    <DeviceTree class="mr-2 w-1/4 xl:w-1/5" @select="handleSelect" />

    <PageWrapper content-full-height fixed-height dense class="w-3/4 overflow-hidden xl:w-4/5">
      <AdVxeTable
        @register="registerTable"
        @checkbox-change="
          () => {
            hasRowSelected = getSelectedRows()?.length > 0;
          }
        "
        @fetch-success="clearSelectedRows"
        @fetch-error="clearSelectedRows"
      >
        <template #tools>
          <Authority value="Root.IoT.Admin.Device.WriteVariable">
            <a-button color="warning" @click="handleWriteVariable" :disabled="!hasRowSelected">
              <Icon icon="material-symbols:upload-sharp" />{{ t('iot.route.device.variable.writeValue') }}
            </a-button>
          </Authority>
          <Authority value="Root.IoT.Admin.Device.CreateVariable">
            <a-button type="primary" @click="handleCreate">
              <Icon icon="ant-design:plus-circle-outlined" />{{ t('common.addText') }}
            </a-button>
          </Authority>
          <Authority value="Root.IoT.Admin.Device.DeleteVariable">
            <a-button type="primary" color="error" :disabled="!hasRowSelected" @click="handleDeleteBatch">
              <Icon icon="ant-design:delete-outlined" />{{ t('common.delText') }}
            </a-button>
          </Authority>
          <Authority value="Root.IoT.Admin.Device.CreateVariable">
            <ImpExcel @success="handleImport">
              <a-button color="success"> <Icon icon="solar:import-outline" />{{ t('common.importText') }} </a-button>
            </ImpExcel>
          </Authority>
          <a-button color="success" @click="handleExport">
            <Icon icon="solar:export-outline" />{{ t('common.exportText') }}
          </a-button>
        </template>

        <template #actionCol="{ row }">
          <TableAction
            outside
            :actions="[
              {
                icon: 'ant-design:delete-outlined',
                color: 'error',
                tooltip: t('common.delText'),
                auth: 'Root.IoT.Admin.Device.DeleteVariable', // 权限控制
                // ifShow: (_action) => {
                //   return row.Deletable === true; // 根据业务控制是否显示: 是否可删除的数据权限状态
                // },
                popConfirm: {
                  title: t('common.delConfirmText'),
                  placement: 'left',
                  confirm: handleDelete.bind(null, row),
                },
              },
            ]"
            :drop-down-actions="[
              {
                icon: 'clarity:details-line',
                label: t('common.detailText'),
                onClick: handleView.bind(null, row),
              },
              {
                icon: 'clarity:note-edit-line',
                label: t('common.editText'),
                auth: 'Root.IoT.Admin.Device.UpdateVariable', // 权限控制
                // ifShow: (_action) => {
                //   return row.Updatable === true; // 根据业务控制是否显示: 是否可更新的数据权限状态
                // },
                onClick: handleEdit.bind(null, row),
              },
              {
                icon: 'eos-icons:state',
                label: t('iot.route.state.variable.title'),
                auth: 'Root.IoT.Admin.VariableState.Read', // 权限控制
                // ifShow: (_action) => {
                //   return row.Updatable === true; // 根据业务控制是否显示: 是否可更新的数据权限状态
                // },
                onClick: handleState.bind(null, row),
              },
            ]"
          />
        </template>
      </AdVxeTable>
    </PageWrapper>

    <DeviceVariableModal @register="registerDetailFormModal" :after-submit-func="handleAfterDetailSubmit" />
    <DeviceVariableWriteModal @register="registerWriteFormModal" :after-submit-func="handleAfterWriteSubmit" />
    <DeviceVariableStateModal @register="registerStateFormModal" />
  </PageWrapper>
</template>

<script lang="ts" setup>
  import type { ExcelData } from '@/components/Excel';

  import type { AjaxResult } from '#/request';

  import { h, onBeforeUnmount, onMounted, ref } from 'vue';

  // import { DeviceVariableIdentity } from '@/api/iot/model';
  // import { getDeviceVariableByIdentity } from '@/api/iot';
  import { isString } from '@eacloud/utils';

  import { createDeviceVariable, deleteDeviceVariable, readDeviceVariable } from '@/api/iot/admin/device';
  import { useModal } from '@/components/AdVxeModal';
  import { AdVxeTable, TableAction, useAdVxeTable } from '@/components/AdVxeTable';
  import { Authority } from '@/components/Authority';
  import { ImpExcel, jsonToSheetXlsx } from '@/components/Excel';
  import Icon from '@/components/Icon/Icon.vue';
  import { PageWrapper } from '@/components/Page';
  import { FilterOperateEnum } from '@/enums/filterOperateEnum';
  import { FormModeEnum } from '@/enums/formEnum';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useMessage } from '@/hooks/web/useMessage';
  import { useIdentityStoreWithOut } from '@/store/modules/identity';
  import DeviceTree from '@/views/iot/device/device/DeviceTree.vue';

  import { FilterGroup, FilterRule } from '#/request';

  import DeviceVariableModal from './detail.vue';
  import DeviceVariableStateModal from './state.vue';
  import { columns } from './variable.data';
  import DeviceVariableWriteModal from './write.vue';

  defineOptions({ name: 'DeviceVariablePage' });

  const { t } = useI18n();
  const { createConfirm, createMessage } = useMessage();

  const useIdentityStore = useIdentityStoreWithOut();
  const signalrHub = useIdentityStore.getSignalRHub;

  // const intervalTimer = ref<any>(null);

  const loadingRef = ref(false);
  function openWrapLoading() {
    loadingRef.value = true;
  }
  function closeWrapLoading() {
    loadingRef.value = false;
  }

  const hasRowSelected = ref(false);
  const deviceRef = ref<any>(null);

  const [registerTable, { getTable, reload, setProps }] = useAdVxeTable({
    id: 'iot-device-variable-page-table',
    // 表标题呈现器
    title: t('iot.route.device.variable.variableList'),
    // 表格数据接口请求对象
    api: readDeviceVariable,
    // 详情表单
    detailForm: {
      // 表单标识
      formIndex: 'iot_devicevariable_detail',
      // 主键字段
      keyField: 'Id',
      // 详情表单抬头
      title: t('iot.route.device.variable.title'),
    },
    // 表单列信息 AdColumn[]
    columns,
    // 使用搜索表单
    searchForm: true,
    // 行选择设置
    selection: 'checkbox',
    // 是否带有边框 boolean | default（默认）, full（完整边框）, outer（外边框）, inner（内边框）, none（无边框）
    border: false,
    // 是否显示序号列
    showSeqColumn: true,
    // 表格右侧操作列配置 AdColumn
    actionColumn: {
      width: 80,
      title: t('common.actionText'),
      fixed: 'right',
      slots: { default: 'actionCol' },
    },
  });

  function getSelectedRows() {
    const $table = getTable();
    if ($table) {
      const rows = $table.getCheckboxRecords();
      return rows;
    }
    return [];
  }
  function clearSelectedRows() {
    const $table = getTable();
    if ($table) {
      $table.clearCheckboxRow();
    }
  }
  function getTableData() {
    const $table = getTable();
    let tableData: any[] = [];
    if ($table) {
      tableData = $table.getTableData()?.tableData || [];
    }
    return tableData;
  }
  async function reloadRow(rows: any, record?: any) {
    const $table = getTable();
    if ($table) {
      await $table.reloadRow(rows, record);
    }
  }

  /** 处理设备选择 */
  async function handleSelect(key: any, e: any) {
    let searchInfo: FilterGroup | undefined;
    if (!e.node.group) {
      if (key) {
        deviceRef.value = {
          Id: key,
          Name: e.node.title,
          DvcGrpId: e.node.DvcGrpId,
          DriverId: e.node.DriverId,
        };
        searchInfo = new FilterGroup();
        searchInfo.Rules.push(new FilterRule('DeviceId', key, FilterOperateEnum.Equal));
      } else {
        deviceRef.value = null;
        searchInfo = undefined;
      }
    } else {
      deviceRef.value = null;
      searchInfo = undefined;
    }
    setProps({ searchInfo });
    await reload();
  }

  const [registerWriteFormModal, writeFormModalMethods] = useModal();
  /** 处理写入设备变量 */
  async function handleWriteVariable() {
    const selectedRows = getSelectedRows();
    if (selectedRows?.length > 0) {
      try {
        openWrapLoading();
        writeFormModalMethods.openModal(true, {
          record: selectedRows,
        });
        // const recordIds = selectedRows.map((item) => {
        //   return item.Id;
        // });
        // const result = await deleteDeviceConfig(recordIds);
        // if (result.Succeeded) {
        //   createMessage.success(t('common.successText'));
        //   await reload();
        //   clearSelectedRows();
        // }
      } finally {
        closeWrapLoading();
      }
    }
  }

  const [registerDetailFormModal, detailFormModalMethods] = useModal();
  /** 处理创建 */
  async function handleCreate() {
    const deviceId = deviceRef.value?.Id;
    const deviceName = deviceRef.value?.Name;
    detailFormModalMethods.openModal(true, {
      formMode: FormModeEnum.Add,
      record: { DeviceId: deviceId, DeviceName: deviceName },
    });
  }
  /** 处理查看 */
  async function handleView(record: any) {
    if (record && record.Id) {
      openWrapLoading();
      try {
        // TODO:详情表单的弹窗
        detailFormModalMethods.openModal(true, {
          formMode: FormModeEnum.ReadOnly,
          record,
        });
      } finally {
        closeWrapLoading();
      }
    }
  }
  /** 处理编辑 */
  async function handleEdit(record: any) {
    if (record && record.Id) {
      openWrapLoading();
      try {
        // TODO:详情表单的弹窗
        detailFormModalMethods.openModal(true, {
          formMode: FormModeEnum.Edit,
          record,
        });
      } finally {
        closeWrapLoading();
      }
    }
  }

  const [registerStateFormModal, stateFormModalMethods] = useModal();
  /** 处理查看状态 */
  async function handleState(record: any) {
    if (record && record.Id) {
      openWrapLoading();
      try {
        const searchInfo: FilterGroup = new FilterGroup();
        searchInfo.Rules.push(new FilterRule('VariableId', record.Id, FilterOperateEnum.Equal));
        stateFormModalMethods.openModal(true, {
          searchInfo,
        });
      } finally {
        closeWrapLoading();
      }
    }
  }

  /** 处理详情表单提交后回调，返回true关闭窗体 */
  async function handleAfterDetailSubmit(formMode: FormModeEnum, result?: AjaxResult | null, _record?: any) {
    if (result) {
      if (result?.Succeeded) {
        if (result?.Content) {
          createMessage.success(result.Content);
        } else {
          createMessage.success(t('common.successText'));
        }
        switch (formMode) {
          case FormModeEnum.Add:
          case FormModeEnum.Edit:
          case FormModeEnum.Delete:
            await reload();
            break;
        }
        return true;
      } else {
        return false;
      }
    }
    return true;
  }

  /** 处理删除 */
  async function handleDelete(record: any) {
    // console.log(record);
    try {
      openWrapLoading();
      const result = await deleteDeviceVariable([record.Id]);
      if (result.Succeeded) {
        createMessage.success(t('common.successText'));
        reload();
        clearSelectedRows();
      }
    } finally {
      closeWrapLoading();
    }
  }
  /** 处理批量删除 */
  async function handleDeleteBatch() {
    const selectedRows = getSelectedRows();
    if (selectedRows?.length > 0) {
      createConfirm({
        zIndex: 999999999,
        iconType: 'warning',
        title: () => h('span', t('sys.app.logoutTip')),
        content: () => h('span', t('common.delConfirmText')),
        onOk: async () => {
          try {
            openWrapLoading();
            const recordIds = selectedRows.map((item) => {
              return item.Id;
            });
            const result = await deleteDeviceVariable(recordIds);
            if (result.Succeeded) {
              createMessage.success(t('common.successText'));
              await reload();
              clearSelectedRows();
            }
          } finally {
            closeWrapLoading();
          }
        },
      });
    }
  }

  /** 处理导入 */
  async function handleImport(record: ExcelData[]) {
    // console.log(record);
    // let tableList: any[] = [];
    // for (const excelData of record) {
    //   const {
    //     header,
    //     results,
    //     meta: { sheetName },
    //   } = excelData;
    //   const columns: any[] = [];
    //   for (const title of header) {
    //     columns.push({ title, dataIndex: title });
    //   }
    //   tableList.push({ title: sheetName, dataSource: results, columns });
    // }
    if (record[0]) {
      const { results } = record[0];
      createConfirm({
        zIndex: 999999999,
        iconType: 'warning',
        title: () => h('span', t('sys.app.logoutTip')),
        content: () => h('span', t('common.importConfirmText')),
        onOk: async () => {
          try {
            openWrapLoading();
            const dtos: any[] = results.map((item) => {
              const dto: { [key: string]: any } = {};
              for (const key in item) {
                if (Object.prototype.hasOwnProperty.call(item, key)) {
                  // console.log(item[key], key);
                  const field = columns.filter((o) => o.title === key)[0]?.field;
                  let value = item[key];
                  if (isString(value)) {
                    value = value?.replace(/\s+/g, '');
                  }
                  dto[field || key] = value || undefined;
                }
              }
              return dto;
            });
            const result = await createDeviceVariable(dtos);
            if (result.Succeeded) {
              createMessage.success(t('common.successText'));
              await reload();
              clearSelectedRows();
            }
          } finally {
            closeWrapLoading();
          }
        },
      });
    }
  }
  /** 处理导出 */
  function handleExport() {
    try {
      openWrapLoading();
      const tableData = getTableData().map((item) => {
        return {
          Id: item.Id,
          DeviceId: item.DeviceId,
          DeviceName: item.DeviceName,
          Name: item.Name,
          Description: item.Description,
          ReadMethod: item.ReadMethod,
          ReadAddress: item.ReadAddress,
          WriteMethod: item.WriteMethod,
          WriteAddress: item.WriteAddress,
          ValueType: item.ValueType,
          ValueNormal: item.ValueNormal,
          Endian: item.Endian,
          Expression: item.Expression,
          Upload: item.Upload,
          PermissionType: item.PermissionType,
          OrderNumber: item.OrderNumber,
          Remark: item.Remark,
          // CreatorId: item.CreatorId,
          // CreatorName: item.CreatorName,
          // CreatorNickname: item.CreatorNickname,
          // CreatedTime: item.CreatedTime,
          // UpdaterId: item.UpdaterId,
          // UpdaterName: item.UpdaterName,
          // UpdaterNickname: item.UpdaterNickname,
          // UpdatedTime: item.UpdatedTime,
        };
      });
      const tableHeader: { [key: string]: any } = {};
      for (const key in tableData[0]) {
        if (Object.prototype.hasOwnProperty.call(tableData[0], key)) {
          // console.log(tableData[0][key], key);
          tableHeader[key] = columns.filter((o) => o.field === key)[0]?.title;
        }
      }
      jsonToSheetXlsx({
        data: tableData,
        header: tableHeader,
        filename: `${t('iot.route.device.variable.title')}.xlsx`,
        sheetName: t('iot.route.device.variable.title'),
      });
    } finally {
      closeWrapLoading();
    }
  }

  /** 处理变量写入表单提交后回调，返回true关闭窗体 */
  async function handleAfterWriteSubmit(_record?: any, _dtos?: any, result?: AjaxResult | null) {
    if (result) {
      if (result?.Succeeded) {
        if (result?.Content) {
          createMessage.success(result.Content);
        } else {
          createMessage.success(t('common.successText'));
        }
        // await reload();
        return true;
      } else {
        return false;
      }
    }
    return true;
  }

  // #region "监听变量"
  // function listenVariables() {
  //   // 每1秒检测变量状态
  //   intervalTimer.value = setInterval(async () => {
  //     const tableData = getDataSource();
  //     if (tableData?.length > 0) {
  //       try {
  //         const dtos: DeviceVariableIdentity[] = tableData.map((item) => {
  //           return {
  //             DeviceName: item.DeviceName,
  //             VariableName: item.Name,
  //           };
  //         });
  //         const variables = await getDeviceVariableByIdentity(dtos, 'none');
  //         if (variables?.length > 0) {
  //           variables.forEach((m) => {
  //             let tableRecords = tableData
  //               .filter((o) => o.DeviceName === m.DeviceName && o.Name === m.VariableName)
  //               .map((m) => m);
  //             if (tableRecords?.length > 0) {
  //               let tableRecord = tableRecords[0];
  //               if (tableRecord) {
  //                 tableRecord = {
  //                   ...tableRecord,
  //                   Status: m.Status,
  //                   Message: m.Message,
  //                   Value: m.Value?.toString(),
  //                   CookedValue: m.CookedValue?.toString(),
  //                   Timestamp: m.Timestamp,
  //                   AlarmStatus: m.AlarmStatus,
  //                 };
  //                 // console.log('listenVariables', m.Value);
  //                 updateTableDataRecord(tableRecord.key, tableRecord);
  //               }
  //             }
  //           });
  //         }
  //       } catch (ex) {
  //         // console.log(ex);
  //       }
  //     }
  //   }, 1000);
  // }
  // #endregion

  // 组件挂载完成后执行的函数
  onMounted(() => {
    // listenVariables();
    startListenMessage();
  });
  // 组件卸载前执行的函数
  onBeforeUnmount(() => {
    // console.log('onBeforeUnmount');
    // if (intervalTimer.value) {
    //   clearInterval(intervalTimer.value); // 清除定时器
    //   intervalTimer.value = null; // 定时器的变量赋值null
    // }
    stopListenMessage();
  });

  /** 启动监听消息 */
  function startListenMessage() {
    signalrHub?.on('IOT_DEVICE_RESPONSE', async (msg: any) => {
      // console.log('IOT_DEVICE_RESPONSE', msg);
      const tableData = getTableData();
      if (tableData?.length > 0) {
        try {
          const deviceName = msg.DeviceName;
          const variableName = msg.VariableName;
          const tableRecords = tableData
            .filter((o) => o.DeviceName === deviceName && o.Name === variableName)
            .map((m) => m);
          if (tableRecords?.length > 0) {
            const row = tableRecords[0];
            const result = msg.Result;
            if (row) {
              const record = {
                ...row,
                Status: result.Status,
                Message: result.Message,
                Value: result.Value?.toString(),
                CookedValue: result.CookedValue?.toString(),
                Timestamp: result.Timestamp,
                AlarmStatus: result.AlarmStatus,
              };
              await reloadRow(row, record);
            }
          }
        } catch (ex) {
          console.error(ex);
        }
      }
    });
  }
  /** 停止监听消息 */
  function stopListenMessage() {
    signalrHub?.off('IOT_DEVICE_RESPONSE');
  }
</script>
